﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using ProgNetComponents.Classes;

namespace ProgNetComponentsDx.Chat
{
    public static class ChatTools
    {
        public static byte[] GetBytes(string msg)
        {
            byte[] bytes = new byte[0];
            try
            {
                bytes = Encoding.UTF8.GetBytes(msg);
            }
            catch { }
            return bytes;
        }
        public static string GetString(byte[] bytes, int count)
        {
            string s = string.Empty;
            try
            {
                s = Encoding.UTF8.GetString(bytes, 0, count);
            }
            catch { }
            return s;
        }
        public static string GetString(byte[] bytes)
        {
            return GetString(bytes, bytes.Length);
        }
        public static byte[] GetBytes(string messageType, string to, string message)
        {
            string msg = ChatMessages.FullMessage.XFormat(messageType, to, message);
            return GetBytes(msg);
        }
        public static byte[] GetBytes(ChatMessageInfo info)
        {
            return GetBytes(info.FormatMessage());
        }
        public static void SendMessage(this NetworkStream stream, ChatMessageInfo info)
        {
            byte[] bytes = ChatTools.GetBytes(info);
            if (info.FileBytes != null)
            {
                List<byte> list = new List<byte>();
                list.AddRange(bytes);
                list.AddRange(info.FileBytes);
                stream.Write(list.ToArray(), 0, list.Count);
                list.Clear();
            }
            else
            {
                stream.Write(bytes, 0, bytes.Length);
            }
            stream.Flush();
            System.Threading.Thread.Sleep(50);
        }
        public static ChatMessageInfo ReceiveMessage(this NetworkStream stream, ObjectHolder<bool> exited)
        {
            ChatMessageInfo info = new ChatMessageInfo();
            stream.ReceiveMessage(exited, info);
            return info;
        }
        public static void ReceiveMessage(this NetworkStream stream, ObjectHolder<bool> exited, ChatMessageInfo info)
        {
            List<byte> bytes = new List<byte>();
            int arraySize = 4096;
            byte[] inStream = new byte[arraySize];
            if (stream.CanRead)
            {
                if (exited.Value)
                    return;

                while (!stream.DataAvailable && !exited.Value)
                {
                    if (exited.Value)
                        return;

                    if (!stream.CanRead)
                        break;
                    System.Threading.Thread.Sleep(10);
                }
                if (exited.Value)
                    return;
                
                while (stream.DataAvailable)
                {
                    if (exited.Value)
                        return;

                    int bytesRead = stream.Read(inStream, 0, arraySize);
                    if (bytesRead == arraySize)
                    {
                        bytes.AddRange(inStream);
                    }
                    else
                    {
                        bytes.AddRange(inStream.Take(bytesRead));
                    }
                }
                info.ParseMessage(bytes.ToArray());
            }
        }
    }
}
